/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.notice.service.impl;

import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.qiniu.util.Auth;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseEntity;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tenant.annotation.TenantIgnore;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.notice.dto.MiddleMessageListSearchDTO;
import org.springblade.modules.notice.dto.MiddleMessageTemplateSaveDTO;
import org.springblade.modules.notice.dto.TemplateVariablesFormDTO;
import org.springblade.modules.notice.entity.BizMsgConfigRelation;
import org.springblade.modules.notice.entity.MiddleMessageTemplate;
import org.springblade.modules.notice.entity.MiddleMessageTemplateVariables;
import org.springblade.modules.notice.enums.BusinessType;
import org.springblade.modules.notice.enums.TemplateSystemStatusEnum;
import org.springblade.modules.notice.enums.TemplateVariableType;
import org.springblade.modules.notice.enums.placeholder.RepairVariable;
import org.springblade.modules.notice.enums.placeholder.VariableEnum;
import org.springblade.modules.notice.service.IBizMsgConfigRelationService;
import org.springblade.modules.notice.service.IBizMsgConfigService;
import org.springblade.modules.notice.service.IMiddleMessageTemplateVariablesService;
import org.springblade.modules.notice.utils.VariableUtil;
import org.springblade.modules.notice.vo.MessageTemplateConfigListVO;
import org.springblade.modules.notice.mapper.MiddleMessageTemplateMapper;
import org.springblade.modules.notice.service.IMiddleMessageTemplateService;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.modules.notice.vo.MiddleMessageTemplateDetailVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 梯无忧_消息通知_模板表 服务实现类
 * @author ysq
 * @since 2024-11-20
 */
@Service
public class MiddleMessageTemplateServiceImpl extends BaseServiceImpl<MiddleMessageTemplateMapper, MiddleMessageTemplate> implements IMiddleMessageTemplateService {

	private IMiddleMessageTemplateVariablesService variablesService;

	private IBizMsgConfigRelationService bizMsgConfigRelationService;

	@Autowired
	public void setVariablesService(IMiddleMessageTemplateVariablesService variablesService) {
		this.variablesService = variablesService;
	}

	@Autowired
	public void setBizMsgConfigRelationService(IBizMsgConfigRelationService bizMsgConfigRelationService) {
		this.bizMsgConfigRelationService = bizMsgConfigRelationService;
	}

	@Override
	@TenantIgnore
	public IPage<MessageTemplateConfigListVO> listByConditionAdmin(IPage<MessageTemplateConfigListVO> page, MiddleMessageListSearchDTO searchDTO) {
		searchDTO.setTenantId(AuthUtil.getTenantId());
		IPage<MessageTemplateConfigListVO> result = baseMapper.listByCondition(page, searchDTO);
		List<MessageTemplateConfigListVO> records = result.getRecords();
		if(Func.isNotEmpty(records)){
			records.forEach(f -> {
				Integer businessType = f.getBusinessType();
				if(!Func.isNull(businessType)){
					String desc = BusinessType.getDesc(businessType);
					f.setBusinessName(desc);
				}
			});
		}
		result.setRecords(records);
		return result;
	}

	@TenantIgnore
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Long saveAndRelation(MiddleMessageTemplateSaveDTO saveDTO) {
		if (Func.isNull(saveDTO.getId())) {
			if(BladeConstant.ADMIN_TENANT_ID.equals(AuthUtil.getTenantId())){
				saveDTO.setSystemDefault(0);
			}else{
				saveDTO.setSystemDefault(1);
				saveDTO.setTenantId(AuthUtil.getTenantId());
			}
		}

		// 1. 保存模板
		MiddleMessageTemplate template = new MiddleMessageTemplate();
		BeanUtil.copyProperties(saveDTO, template);
		boolean isSuccess = this.saveOrUpdate(template);
		Long currentTemplateId = template.getId();

		// 2. 变量处理
		List<TemplateVariablesFormDTO> templateContentList = saveDTO.getTitleList();
		List<MiddleMessageTemplateVariables> titleList = new ArrayList<>();
		List<MiddleMessageTemplateVariables> contentList = new ArrayList<>();
		if(Func.isNotEmpty(templateContentList)){
			for (int i = 0; i < templateContentList.size(); i++) {
				TemplateVariablesFormDTO templateVariablesFormDTO = templateContentList.get(i);
				String variableName = templateVariablesFormDTO.getName();
				List<MiddleMessageTemplateVariables> list = templateVariablesFormDTO.getList();
				if(Func.isNotEmpty(list)){
					for(int j = 0 ; j < list.size() ; j++){
						MiddleMessageTemplateVariables middleMessageTemplateVariables = list.get(j);
						middleMessageTemplateVariables.setId(null);
						middleMessageTemplateVariables.setVariableName(variableName);
						middleMessageTemplateVariables.setRowSort(i);
						middleMessageTemplateVariables.setColumnSort(j);
						middleMessageTemplateVariables.setTemplateId(currentTemplateId);
						middleMessageTemplateVariables.setVariableType(TemplateVariableType.TITLE.getType());
						middleMessageTemplateVariables.setTenantId(AuthUtil.getTenantId());
						titleList.add(middleMessageTemplateVariables);
					}
				}
			}
		}
		List<TemplateVariablesFormDTO> variablesList = saveDTO.getContentList();
		if(Func.isNotEmpty(variablesList)){
			for (int i = 0; i < variablesList.size(); i++) {
				TemplateVariablesFormDTO templateVariablesFormDTO = variablesList.get(i);
				String variableName = templateVariablesFormDTO.getName();
				List<MiddleMessageTemplateVariables> list = templateVariablesFormDTO.getList();
				if(Func.isNotEmpty(list)){
					for(int j = 0 ; j < list.size() ; j++){
						MiddleMessageTemplateVariables middleMessageTemplateVariables = list.get(j);
						middleMessageTemplateVariables.setId(null);
						middleMessageTemplateVariables.setVariableName(variableName);
						middleMessageTemplateVariables.setRowSort(i);
						middleMessageTemplateVariables.setColumnSort(j);
						middleMessageTemplateVariables.setTemplateId(currentTemplateId);
						middleMessageTemplateVariables.setVariableType(TemplateVariableType.CONTENT.getType());
						middleMessageTemplateVariables.setTenantId(AuthUtil.getTenantId());
						contentList.add(middleMessageTemplateVariables);
					}
				}
			}
		}
        // 3. 覆盖变量
		// 当是更新的情况，需要先删除原有变量
		if(!Func.isNull(saveDTO.getId())){
			MiddleMessageTemplate existTemplate = this.getById(saveDTO.getId());
			if(Func.isNull(existTemplate)){
				throw new ServiceException("消息模板不存在，删除失败，请联系管理员");
			}
			variablesService.remove(new LambdaQueryWrapper<MiddleMessageTemplateVariables>()
				.eq(MiddleMessageTemplateVariables::getTemplateId, saveDTO.getId())
			);
		}
		// 保存变量

		if(Func.isNotEmpty(titleList)){
			variablesService.saveBatch(titleList);
		}
		if(Func.isNotEmpty(contentList)){
			variablesService.saveBatch(contentList);
		}
		// 4. 返回模板id
		if(isSuccess){
			String messageTitleFull = "";
			String messageContentFull = "";
			Integer businessType = template.getBusinessType();
			Long templateId = template.getId();
			List<MiddleMessageTemplateVariables> variables = variablesService.list(
				new LambdaQueryWrapper<MiddleMessageTemplateVariables>()
					.eq(MiddleMessageTemplateVariables::getTemplateId, templateId)
					.eq(BaseEntity::getIsDeleted, 0)
			);
			List<MiddleMessageTemplateVariables> titleFullList = variables.stream().filter(t -> new Integer(1).equals(t.getVariableType())).collect(Collectors.toList());
			List<MiddleMessageTemplateVariables> contentFullList = variables.stream().filter(t -> new Integer(2).equals(t.getVariableType())).collect(Collectors.toList());
			messageContentFull = this.getVarString(contentFullList, businessType);
			messageTitleFull = this.getVarString(titleFullList, businessType);
			template.setMessageTitleFull(messageTitleFull);
			template.setMessageContentFull(messageContentFull);
			this.updateById(template);
			return templateId;
		}
		return null;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean removeAndUnbind(Long id) {
		MiddleMessageTemplate template = this.getById(id);
		if(Func.isNull(template)){
			throw new ServiceException("消息模板不存在，或该消息模板为系统默认模板，删除失败，请联系管理员");
		}
		// 判断当前模板是否已被使用
		List<BizMsgConfigRelation> uesdList = bizMsgConfigRelationService.list(new LambdaQueryWrapper<BizMsgConfigRelation>()
			.eq(BizMsgConfigRelation::getMsgTemplateId, id));
		if(Func.isNotEmpty(uesdList)){
			throw new ServiceException("该消息模板已被使用，请先解除关联关系后再删除");
		}
		// remove variables
		boolean removeVariables = variablesService.remove(
			Wrappers
				.<MiddleMessageTemplateVariables>lambdaQuery()
				.eq(MiddleMessageTemplateVariables::getTemplateId, id)
		);
		// 删除模板
		boolean removeTemplate = this.removeById(id);
		return removeVariables && removeTemplate;
	}

	@Override
	@TenantIgnore
	public MiddleMessageTemplateDetailVO detailById(Long id) {
		MiddleMessageTemplateDetailVO result = new MiddleMessageTemplateDetailVO();
		// 主表
		MiddleMessageTemplate template = this.getById(id);
		if (Func.isNull(template)) {
			return result;
		}
		BeanUtil.copyProperties(template, result);
		// 变量表
		List<List<MiddleMessageTemplateVariables>> titleAndVariablesList = new ArrayList<>();
		List<List<MiddleMessageTemplateVariables>> contentAndVariablesList = new ArrayList<>();
		// 变量处理
		List<MiddleMessageTemplateVariables> variables = variablesService.list(
			Wrappers.<MiddleMessageTemplateVariables>lambdaQuery()
				.eq(MiddleMessageTemplateVariables::getTemplateId, id));

		// 根据变量类型拆分成两个大列表，并根据RowSort排序
		List<MiddleMessageTemplateVariables> titleList = variables
			.stream()
			.filter(f -> TemplateVariableType.TITLE.getType().equals(f.getVariableType()))
			.sorted(Comparator.comparing(MiddleMessageTemplateVariables::getRowSort))
			.collect(Collectors.toList());
		List<MiddleMessageTemplateVariables> contentList = variables
			.stream()
			.filter(f -> TemplateVariableType.CONTENT.getType().equals(f.getVariableType()))
			.sorted(Comparator.comparing(MiddleMessageTemplateVariables::getRowSort))
			.collect(Collectors.toList());

		// 根据纵向排序分成子列表,同一个排序值的变量放在同一个子列表,子列表根据横向排序排序
		titleList.stream().collect(Collectors.groupingBy(MiddleMessageTemplateVariables::getRowSort)).forEach((k, v) -> {
			titleAndVariablesList.add(ListUtil
					.toList(v)
					.stream()
					.sorted(Comparator.comparing(MiddleMessageTemplateVariables::getColumnSort))
					.collect(Collectors.toList()));
		});
		contentList.stream().collect(Collectors.groupingBy(MiddleMessageTemplateVariables::getRowSort)).forEach((k, v) -> {
			contentAndVariablesList.add(ListUtil
					.toList(v)
					.stream()
					.sorted(Comparator.comparing(MiddleMessageTemplateVariables::getColumnSort))
					.collect(Collectors.toList()));
		});
		List<TemplateVariablesFormDTO> titleStructureList = new ArrayList<>();
		List<TemplateVariablesFormDTO> contentStructureList = new ArrayList<>();
		Integer businessType = template.getBusinessType();
		titleAndVariablesList.forEach(t -> {
			if(Func.isNotEmpty(t)){
//				t.forEach(v -> {
//					if(new Integer(2).equals(v.getVariableInputType())) {
//						try{
//							Integer code = Integer.valueOf(v.getVariableValue());
//							String descByCodeAndBusinessType = this.getDescByCodeAndBusinessType(code, businessType);
//							v.setDesc(descByCodeAndBusinessType);
//						}
//						catch (Exception e){
//							throw new ServiceException("下拉选择变量值必须为code");
//						}
//					}
//				});
				TemplateVariablesFormDTO formDTO = new TemplateVariablesFormDTO();
				MiddleMessageTemplateVariables middleMessageTemplateVariables = t.get(0);
				if(!Func.isNull(middleMessageTemplateVariables)){
					formDTO.setName(middleMessageTemplateVariables.getVariableName());
				}
				formDTO.setList(t);
				titleStructureList.add(formDTO);
			}
		});
		contentAndVariablesList.forEach(t -> {
			if(Func.isNotEmpty(t)){
//				t.forEach(v -> {
//					if(new Integer(2).equals(v.getVariableInputType())) {
//						try{
//							Integer code = Integer.valueOf(v.getVariableValue());
//							String descByCodeAndBusinessType = this.getDescByCodeAndBusinessType(code, businessType);
//							v.setDesc(descByCodeAndBusinessType);
//						}
//						catch (Exception e){
//							throw new ServiceException("下拉选择变量值必须为code");
//						}
//					}
//				});
				TemplateVariablesFormDTO formDTO = new TemplateVariablesFormDTO();
				MiddleMessageTemplateVariables middleMessageTemplateVariables = t.get(0);
				if(!Func.isNull(middleMessageTemplateVariables)){
					formDTO.setName(middleMessageTemplateVariables.getVariableName());
				}
				formDTO.setList(t);
				contentStructureList.add(formDTO);
			}
		});
		result.setTitleStructureList(titleStructureList);
		result.setContentStructureList(contentStructureList);
		result.setTitleList(titleAndVariablesList);
		result.setContentList(contentAndVariablesList);
		return result;
	}

	private void getLists(List<List<MiddleMessageTemplateVariables>> listList, Long currentTemplateId, TemplateVariableType type) {
		if(Func.isNotEmpty(listList)){
			for(int i = 0 ; i < listList.size() ; i++){
				for(int j = 0 ; j < listList.get(i).size() ; j++){
					MiddleMessageTemplateVariables titleVariable = listList.get(i).get(j);
					// 纵向sort
					titleVariable.setRowSort(i);
					// 横向sort
					titleVariable.setColumnSort(j);
					// 变量类型：id
					titleVariable.setTemplateId(currentTemplateId);
					// 变量类型：标题
					titleVariable.setVariableType(type.getType());
				}
			}
		}
	}
	private String getVarString(List<MiddleMessageTemplateVariables> variables, Integer businessType){
		Class<? extends VariableEnum> variableEnumClass = BusinessType.getVariableEnumClassByCode(businessType);
        return variables.stream().sorted(Comparator.comparing(MiddleMessageTemplateVariables::getColumnSort))
			.map(t -> {
				if (t.getVariableInputType() == 1) {
					// 文本
					return t.getVariableValue();
				} else {
					// 变量
					String var = VariableUtil.getVarByCode(Integer.valueOf(t.getVariableValue()), variableEnumClass);
					return Func.isNull(var) ? "" : var;
				}
			}).collect(Collectors.joining());
	}

//	private String getDescByCodeAndBusinessType(Integer code, Integer businessType){
//		if(new Integer(2).equals(businessType)){
//			return RepairVariable.getDescByCode(code);
//		}
//		return null;
//	}



}
